package cn.wolfcode.p2p.business.service.impl;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.wolfcode.base.QueryObject;
import cn.wolfcode.p2p.base.domain.Account;
import cn.wolfcode.p2p.base.domain.UserInfo;
import cn.wolfcode.p2p.base.service.IAccountService;
import cn.wolfcode.p2p.base.service.IUserInfoService;
import cn.wolfcode.p2p.base.util.BidConst;
import cn.wolfcode.p2p.base.util.BitStateUtil;
import cn.wolfcode.p2p.base.util.DateUtil;
import cn.wolfcode.p2p.base.util.LoginInfoContext;
import cn.wolfcode.p2p.business.domain.BidRequest;
import cn.wolfcode.p2p.business.domain.BidRequestAuditHistory;
import cn.wolfcode.p2p.business.mapper.BidRequestAuditHistoryMapper;
import cn.wolfcode.p2p.business.mapper.BidRequestMapper;
import cn.wolfcode.p2p.business.query.BidRequestQuery;
import cn.wolfcode.p2p.business.service.IBidRequestService;
import cn.wolfcode.p2p.business.util.CalculatetUtil;

@Service
@Transactional
public class BidRequestServiceImpl implements IBidRequestService {
    @Autowired
    private BidRequestMapper bidRequestMapper;
    @Autowired
    private IUserInfoService userInfoService;
    @Autowired
    private IAccountService accountService;
    @Autowired
    private BidRequestAuditHistoryMapper historyMapper;
    
    // 支持高并发的线程安全的队列集合, 存储待发布的借款列表
    private ConcurrentLinkedQueue<BidRequest> queue = new ConcurrentLinkedQueue<>();
	
	@Transactional(readOnly=true)
	public PageInfo<BidRequest> query(QueryObject qo) {
		PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
		List<BidRequest> list = bidRequestMapper.selectList(qo);
		return new PageInfo<BidRequest>(list);
	}

    public void applyBorrow(BidRequest vo) {
	    // 回去当前用户信息
        UserInfo current = userInfoService.get(LoginInfoContext.getCurrentLoginInfo().getId());

        Account account = accountService.get(current.getId());

        // 非法判断
        if (
                current.getBorrowble() // 是否满足借款条件
                && !current.getHasBidRequestInProcess() // 是否存在一个正在处理的借款申请
                && vo.getBidRequestAmount().compareTo(account.getRemainBorrowLimit()) <= 0 // 借款总额小于或等于剩余额度
                && vo.getCurrentRate().compareTo(BidConst.MIN_CURRENT_RATE) >= 0 // 最低年利率
                && vo.getCurrentRate().compareTo(BidConst.MAX_CURRENT_RATE) <= 0 // 最高年利率
                && vo.getMinBidAmount().compareTo(BidConst.MIN_BID_AMOUNT) >= 0 // 最低投标
                && vo.getBidRequestAmount().compareTo(BidConst.MIN_BIDREQUEST_AMOUNT) >= 0 // 最低借款金额

        ) {
            // 创建BidRequest对象
            BidRequest bidRequest = new BidRequest();

            bidRequest.setBidRequestType(BidConst.BIDREQUEST_TYPE_NORMAL); // 借款方式
            bidRequest.setReturnType(BidConst.RETURN_TYPE_MONTH_INTEREST_PRINCIPAL); // 还款类型
            bidRequest.setBidRequestState(BidConst.BIDREQUEST_STATE_APPLY); // 借款状态
            bidRequest.setBidRequestAmount(vo.getBidRequestAmount()); // 借款金额
            bidRequest.setCurrentRate(vo.getCurrentRate()); // 年化利率
            bidRequest.setMinBidAmount(vo.getMinBidAmount()); // 最小投标金额
            bidRequest.setMonthes2return(vo.getMonthes2return()); // 借款期数
            bidRequest.setCurrentSum(BidConst.ZERO); // 当前已投标投标金额
            bidRequest.setTitle(vo.getTitle()); // 借款标题
            bidRequest.setDescription(vo.getDescription()); // 借款描述
            bidRequest.setDisableDays(vo.getDisableDays()); // 招标天数
            bidRequest.setApplyTime(new Date()); // 申请时间
            bidRequest.setCreateUser(LoginInfoContext.getCurrentLoginInfo()); // 借款人

            // 借款总利息
            bidRequest.setTotalRewardAmount(CalculatetUtil.calTotalInterest(
                    bidRequest.getReturnType() // 还款类型
                    , bidRequest.getBidRequestAmount() // 借款金额
                    , bidRequest.getCurrentRate() // 年化利率
                    , bidRequest.getMonthes2return() // 借款期数
            ));
            bidRequestMapper.insert(bidRequest);

        }
        // 添加借款中的状态码
        current.addNewState(BitStateUtil.OP_HAS_BIDREQUEST_PROCESS);
        userInfoService.update(current);
    }

    public void PublishAudit(Long bidRequestId, String publishTime, Integer state, String remark) {

	    // 查询借款对象, 判断非空, 状态
        BidRequest br = this.get(bidRequestId);


        if (br != null && br.getBidRequestState() == BidConst.RETURN_TYPE_MONTH_INTEREST_PRINCIPAL){
            // 创建审核历史对象, 设置信息
/*
            DateUtils.addDays(
                    StringUtils.hasLength(publishTime) ? DateUtil.string2date(publishTime, "yyyy-MM-dd HH:mm") : new Date()
                    , br.getDisableDays())*/

            BidRequestAuditHistory history = new BidRequestAuditHistory();
            history.setBidRequestId(bidRequestId);
            history.setAuditType(BidRequestAuditHistory.PUBLISH_AUDIT);
            history.setState(state);
            history.setRemark(remark);
            history.setAuditTime(new Date());
            history.setApplyTime(br.getApplyTime());
            history.setAuditor(LoginInfoContext.getCurrentLoginInfo());
            history.setApplier(br.getCreateUser());

            historyMapper.insert(history);

            if (state == BidRequestAuditHistory.STATE_PASS){
                // 审核通过, 借款状态
                // 设置修改信息(发标时间, 招标截止时间, 审核风控建议, 借款的状态)
                if (!StringUtils.hasLength(publishTime)) {
                    // 如果publicTime == null 立即发标, 招标中
                    br.setPublishTime(new Date());
                    br.setBidRequestState(BidConst.BIDREQUEST_STATE_BIDDING);
                }else {
                    // 如果publicTime != null 定时发标
                    br.setPublishTime(DateUtil.string2date(publishTime, "yyyy-MM-dd HH:mm"));
                    br.setBidRequestState(BidConst.BIDREQUEST_STATE_PUBLISH_PENDING);
                }
                br.setDisableDate(DateUtils.addDays(br.getPublishTime(), br.getDisableDays()));

            }else {
                // 审核拒绝, 借款状态, 取消借款人的借款中的状态
                br.setBidRequestState(BidConst.BIDREQUEST_STATE_PUBLISH_REFUSE);

                UserInfo userInfo = userInfoService.get(br.getCreateUser().getId());
                userInfo.removerState(BitStateUtil.OP_HAS_BIDREQUEST_PROCESS);
                userInfoService.update(userInfo);
            }
            br.setNote(remark);
            this.update(br);
            
            // 如果发布时间在一个小时之内, 则手动添加到队列中
            if (state == BidRequestAuditHistory.STATE_PASS && StringUtils.hasLength(publishTime)){
            	// 版本号 + 1
            	br.setVersion(br.getVersion() + 1);
            	queue.offer(br);
            }
        }
    }

    @Override
    public BidRequest get(Long id) {
        return bidRequestMapper.selectById(id);
    }

    @Override
    public void update(BidRequest bidRequest) {
        bidRequestMapper.updateById(bidRequest);
    }

    @Override
    public List<BidRequestAuditHistory> listAuditHistorysByBidRequestId(Long BidRequestId) {
        return historyMapper.selsectAuditHistorysByBidRequestId(BidRequestId);
    }

    @Override
    public List<BidRequest> listIndexBidRequest(int number) {
	    BidRequestQuery qo = new BidRequestQuery();
	    // 招标中, 还款中, 已还清, 排序
	    qo.setStates(new int[]{
	            BidConst.BIDREQUEST_STATE_BIDDING
                , BidConst.BIDREQUEST_STATE_PAYING_BACK
                , BidConst.BIDREQUEST_STATE_COMPLETE_PAY_BACK
        });
	    qo.setOrderByBidRequestStateAsAsc(true);
	    PageHelper.startPage(1, number);
        return bidRequestMapper.selectList(qo);
    }

    @Override
    public List<BidRequest> listUnPlushBideRequest(int number) {
    	// 
    	BidRequestQuery qo = new BidRequestQuery();
    	// 查询类型为类型为待发布
    	qo.setBidRequestState(BidConst.BIDREQUEST_STATE_PUBLISH_PENDING);
    	// 按照发布时间升序排序
    	PageHelper.startPage(1, number, "br.publish_time asc");
        return bidRequestMapper.selectList(qo);
    }

	public void listUnPublishedRequestInOneHour() {
		// 获取最近一个
		Date endDate = DateUtils.addDays(new Date(), 1);
		List<BidRequest> list = bidRequestMapper.selectUnPublishedRequestInOneHour(BidConst.BIDREQUEST_STATE_PUBLISH_PENDING, endDate);
		
		for (BidRequest br : list) {
			// 判断是否已经在队列中
			if(!queue.contains(br)){
				// 把待发布的列表存进队列中
				queue.offer(br);
			}
		}
	}

	@Override
	public void publishedBidRequestPreMinute() {
		// 获取当前时间
		Date nowDate = new Date();
		// 迭代器迭代队列
		Iterator<BidRequest> it = queue.iterator();
		while (it.hasNext()){
			BidRequest br = it.next();
			// 如果发布时间小于当前时间, 马上发布
			if (br.getPublishTime().getTime() <= nowDate.getTime()) {
				br.setBidRequestState(BidConst.BIDREQUEST_STATE_BIDDING);
				this.update(br);
				// 用迭代器的删除从队列中移除
				it.remove();
			}
		}
	}
	
	
	
	
	
	
	
	
	
}
